#pragma once
#include <sys/epoll.h>
#include <unistd.h>
#include "log.hpp"
#include "err.hpp"
#include <stdio.h>
#include <string.h>
#include <errno.h>

class Epoller
{
public:
    Epoller() : _epfd(-1)
    {
    }
    ~Epoller()
    {
        if (_epfd > 0)
            close(_epfd);
    }
    void create()
    {
        _epfd = epoll_create(128);
        if (_epfd < 0)
        {
            logMessage(FATAL, "epoll create error : %s", strerror(errno));
            exit(EPOLL_CREATE);
        }
    }

    bool addEvent(int sock, uint32_t event)
    {
        struct epoll_event ev;
        ev.events = event;
        ev.data.fd = sock;

        int n = epoll_ctl(_epfd, EPOLL_CTL_ADD, sock, &ev);
        if (n == -1)
        {
            logMessage(ERROR, "epoll_ctl EPOLL_CTL_ADD error: %s", strerror(errno));
            return false;
        }
        return true;
    }

    int Wait(struct epoll_event rev[], int num, int timeout)
    {
        epoll_wait(_epfd, rev, num, timeout);
    }

    bool control(int sock, uint32_t event, int op)
    {
        if (op & EPOLL_CTL_DEL)
        {
            int ret = epoll_ctl(_epfd, op, sock, nullptr);
            if (ret == -1)
            {
                logMessage(ERROR, "control epoll_ctl EPOLL_CTL_DEL error!! ");
                return false;
            }
        }
        else if (op & EPOLL_CTL_MOD)
        {
            struct epoll_event ev;
            ev.events = event;
            ev.data.fd = sock;
            int ret = epoll_ctl(_epfd, op, sock, &ev);
            if (ret == -1)
            {
                logMessage(ERROR, "control epoll_ctl EPOLL_CTL_MOD error!! ");
                return false;
            }
        }

        return true;
    }

private:
    int _epfd;
};
